package siruna.WE.rendering;

import java.util.ArrayList;
import java.util.HashMap;

import siruna.WE.Global;
import siruna.WE.R;
import siruna.WE.FileManager.FileManager;
import siruna.WE.installwidgets.InstallWidgets;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;

/**
 * Klasse die gebruikt wordt om de view te tonen, gebruikt bij het installeren
 * van een widget
 * 
 * @author Tim
 * 
 */
public class installView extends Activity {
	// ruimte onderaan om de info van een geselcteerde widget te tonen
	private WebView webFooter;
	// mime type, gebruikt om de info te tonen, de info wordt als html bewaard
	String mimeType = "text/html";
	// encoding type, gebruikt om de info te tonen, de info wordt als html
	// bewaard
	String encoding = "utf-8";
	// zoek knop
	private Button buttonZoek;
	// Zoekveld
	private EditText zoekveld;
	// lijst met de titles van de widgets
	private String[] TITLES;
	// view die de lijst toont
	private ListView lv;
	// structuur die de info vanuit het xml bestand op de server bevat
	ArrayList<HashMap<String, String>> res;
	// omgekeerd zoeken mogelijk maken, nr van de geselcterde -> naam
	HashMap<String, Integer> reverse;

	// Resetknop
	private Button buttonReset;
	// filemanager
	private FileManager fm;
	// boolean als er een fout is opgetreden, om een gepaste melding te kunnen
	// tonen
	private boolean error;

	/**
	 * Wordt opgeroepen wanneer de activiteit voor het eerst aangemaakt wordt
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		fm = new FileManager(this);

		setContentView(R.layout.installview);

		lv = (ListView) findViewById(R.id.ListView01);
		webFooter = (WebView) findViewById(R.id.web);
		buttonZoek = (Button) findViewById(R.id.Button01);
		buttonReset = (Button) findViewById(R.id.Button02);
		zoekveld = (EditText) findViewById(R.id.EditText01);

		zoekveld.setNextFocusDownId(R.id.Button01);
		zoekveld.setNextFocusRightId(R.id.Button01);

		SetEnabledControls(false);

		buttonZoek.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// als geklikt op de zoekknop, de juiste uitvoer zoeken en
				// toenen
				// zoeken in de lijst(descripties) en enkel de juiste overhouden
				String zoekstring = zoekveld.getText().toString();
				ArrayList<Integer> zoekindexen = new ArrayList<Integer>();
				for (int i = 0; i < res.size(); i++) {
					String s = res.get(i).get("description");
					if (s.toLowerCase().contains(
							zoekstring.trim().toLowerCase())) {
						zoekindexen.add(i);
					}
				}
				String s = "";
				reverse.clear();
				TITLES = new String[zoekindexen.size()];
				for (int i = 0; i < zoekindexen.size(); i++) {
					int index = zoekindexen.get(i);
					s = res.get(index).get("title");
					TITLES[i] = s;
					reverse.put(s, i);
				}
				buildList();

			}
		});

		buttonReset.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// als geklikt op de reset knop, toon het startscherm terug
				reset();
				buildList();
				zoekveld.setText("");

			}
		});
		lv.setOnItemSelectedListener(new OnItemSelectedListener() {

			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// als een item gesecteerd werd, de gepaste descriptei tonen
				// onderaan.
				TextView tv = (TextView) arg1;
				int index = reverse.get(tv.getText());
				// descriptie is html geformateerd

				String html = "<html><head></head><body>"
						+ res.get(index).get("description") + "</body></html>";
				webFooter.setVisibility(0);
				webFooter.loadDataWithBaseURL("fake://fake.com", html,
						mimeType, encoding, null);

			}

			public void onNothingSelected(AdapterView<?> arg0) {
				// als niets is geselcteerd, niets tonen
				String html = "<html><head></head><body></body></html>";

				webFooter.loadDataWithBaseURL("fake://fake.com", html,
						mimeType, encoding, null);
			}

		});

		lv.setOnFocusChangeListener(new OnFocusChangeListener() {

			public void onFocusChange(View v, boolean hasFocus) {
				if (!hasFocus) {
					// als niets is geselcteerd, niets tonen

					String html = "<html><head></head><body></body></html>";

					webFooter.loadDataWithBaseURL("fake://fake.com", html,
							mimeType, encoding, null);
				}

			}
		});

		lv.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// bij het klikken op een widget, installeer deze widget en keer
				// teurg
				TextView tv = (TextView) arg1;
				int index = reverse.get(tv.getText());
				// System.out.println("url: " +
				// res.get(index).get("download").trim());

				String name = res.get(index).get("title");
				name.lastIndexOf(".zip");
				name = name.substring(0, name.lastIndexOf(".zip"));
				Log.i("TEST", "widget "+name+ " installeren");
				
				fm.installWidget(res.get(index).get("download").trim(), name);
				Log.i("TEST", "widget geinstalleerd");
				// terugkeren naar vorige view
				finish();
			}
		});
		refresh();
		buildList();
	}

	/**
	 * verniew de lijst vanop de server
	 */
	private void refresh() {
		InstallWidgets installWidgets = new InstallWidgets(this);

		res = installWidgets.getDownloadList();
		if (res != null) {
			reset();
		} else {
			error = true;
			errorDialog().show();
		}
	}

	/**
	 * reset, herstel de toestand bij het openen van de view
	 */
	private void reset() {
		webFooter.clearView();
		TITLES = new String[res.size()];
		reverse = new HashMap<String, Integer>();
		String s = "";
		for (int i = 0; i < res.size(); i++) {
			s = res.get(i).get("title");
			TITLES[i] = s;
			reverse.put(s, i);
		}
	}

	/**
	 * bouw de lijst op
	 */
	private void buildList() {
		if (!error) {
			lv.setAdapter(new ArrayAdapter<String>(this,
					android.R.layout.simple_list_item_1, TITLES));
			SetEnabledControls(true);
		}
	}

	/**
	 * enable/disable de knoppen en het zoekveld
	 * 
	 * @param b
	 *            true=enabled, false=disabled
	 */
	private void SetEnabledControls(Boolean b) {
		buttonZoek.setEnabled(b);
		buttonReset.setEnabled(b);
		zoekveld.setEnabled(b);
	}

	/**
	 * Methode die ervoor zorgt dat de juiste opties zichtbaar zijn in het menu
	 */
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		menu.clear();
		menu.add(getString(R.string.exit));
		menu.add(getString(R.string.terug));

		return true;
	}

	/**
	 * Zorg dat de juiste handelingen worden uitgevoerd bij het selecteren van
	 * een optie
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);

		if (item.getTitle().equals(getString(R.string.exit))) {
			this.setResult(Global.SUBACTIVITY_RESULTCODE_CHAINCLOSE);
			this.finish();
		} else if (item.getTitle().equals(getString(R.string.terug))) {
			finish();
		}
		return true;
	}

	/**
	 * knop indrukken opvangen, alleen als er o de return toets wordt gedrukt de
	 * view sluiten
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			this.finish();
		}
		return super.onKeyDown(keyCode, event);

	}

	/**
	 * erordialoog dat getoond wordt wanneer er een probleem is met de
	 * verbinding met de server
	 * 
	 * @return dialoogvenster
	 */
	private Dialog errorDialog() {
		Dialog d = new AlertDialog.Builder(this).setTitle(
				getString(R.string.error)).setMessage(
				getString(R.string.servererror)).setPositiveButton(
				getString(R.string.opnieuw),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						error = false;
						refresh();
						buildList();
					}
				})

		.setNegativeButton(getString(R.string.cancel),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						/* User clicked Cancel so do some stuff */
					}
				}).create();
		return d;
	}

}